package ks.server.controllers.commands.admin.user;

import java.util.Collection;
import java.util.Vector;

import ks.framework.common.Message;
import ks.framework.communicator.Communicator;
import ks.framework.interfaces.IProcessMessage;
import ks.managers.user.User;
import ks.server.ipc.Listener;
import ks.server.persist.PersistentUserManager;
import ks.server.ServerContext;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Process request to delete users.
 * 
 * @author Christopher Page
 */
public class UserDeleteController implements IProcessMessage {

	/** Primary agent to whom we can communicate our messages. */
	Communicator com;
	
	public UserDeleteController (Communicator com) {
		this.com = com;
	}
	
	/**
	 * Process the message
	 * 
	 * @param m The message to process.
	 * @return A boolean value.
	 */
	public boolean process(Message m) {
		PersistentUserManager um = ServerContext.getUserManager();
		
		// Verify that command originator is an admin
		if (um.getUser(m.getOriginator()) == null) {
			Listener.nack(m, 4, "Unable to delete users: what!? I don't even...");
			return true;
		}
		else if (!um.getUser(m.getOriginator()).isAdmin()) {
			Listener.nack(m, 4, "Unable to delete user: access denied.");
			return true;
		}
		
		Vector<String> usersToDelete = new Vector<String>();
		Vector<String> nonexistantUsers = new Vector<String>();
		Vector<String> successfulDeletes = new Vector<String>();
		Vector<String> failedDeletes = new Vector<String>();
		
		NodeList playernameLst = m.contents().getChildNodes();
		Node playernameTmpNode;
		Node playernameNameTmpNode;
		
		int unreadablePlayernameCounter = 0;
		
		// get users to create
		for (int i = 0; i < playernameLst.getLength(); i++) {
			playernameTmpNode = playernameLst.item(i);
			playernameNameTmpNode = playernameTmpNode.getAttributes().getNamedItem("name");
			
			if (playernameNameTmpNode != null) {
				usersToDelete.add(playernameNameTmpNode.getNodeValue());
			}
			else {
				unreadablePlayernameCounter++;
			}
		}
		
		// get usernames of online users
		Collection<String> onlineUsernames = com.getOnlineUsers();
		
		for (String uN : usersToDelete) {
			User u = um.getUser(uN);
			if (u == null) {
				nonexistantUsers.add(uN);
			}
			else {
				if (onlineUsernames.contains(uN)) {
					com.disconnectUser(uN);
				}
				if (um.removeUser(u)) {
					successfulDeletes.add(uN);
				}
				else {
					failedDeletes.add(uN);
				}
			}
		}
		
		String message = "";
		if (successfulDeletes.size() > 0) {
			message += "Successfully deleted:";
			for (String uN : successfulDeletes) {
				message += " " + uN;
			}
			message += ". ";
		}
		
		if (failedDeletes.size() > 0) {
			message += "Unable to delete:";
			for (String uN : failedDeletes) {
				message += " " + uN;
			}
			message += ". ";
		}
		
		if (nonexistantUsers.size() > 0) {
			message += "Nonexistant Users:";
			for (String uN : nonexistantUsers) {
				message += " " + uN;
			}
			message += ". ";
		}
		
		if (unreadablePlayernameCounter > 0) {
			message += unreadablePlayernameCounter + " incorrectly formatted users.";
		}
		
		if (successfulDeletes.size() > 0) {
			Listener.ack(m, message);
			return true;
		}
		else {
			Listener.nack(m, 4, message);
			return true;
		}
	}
}
